package com.haiyi.activiti.engine.framework.activiti.manager.impl;

import com.haiyi.activiti.engine.model.entity.FormModel;
import com.haiyi.activiti.engine.model.entity.ComponentDesign;
import com.haiyi.activiti.engine.model.entity.Process;
import com.haiyi.activiti.engine.model.entity.RuleEngine;
import com.haiyi.activiti.engine.framework.activiti.manager.*;
import com.haiyi.activiti.engine.framework.basic.DateTimeAdapter;
import com.haiyi.activiti.engine.framework.basic.IdBuilder;
import com.haiyi.activiti.engine.framework.basic.SecurityAdapter;
import com.haiyi.activiti.engine.framework.template.StringResolverFactory;
import com.haiyi.activiti.engine.framework.template.freemarker.FreemarkerBuilderAdapter;
import com.haiyi.activiti.engine.query.FormModelQuery;
import com.haiyi.activiti.engine.query.ComponentDesignQuery;
import com.haiyi.activiti.engine.service.IFormModelService;
import com.haiyi.activiti.engine.service.IComponentService;
import com.haiyi.activiti.engine.service.IProcessService;
import com.haiyi.activiti.engine.util.Assert;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;

/**
 * <p> </p>
 *
 * <pre> Created: 2018/12/5 17:21 </pre>
 *
 * @author hlu
 * @version 1.0
 * @since JDK 1.7
 */
@Component
@Transactional(rollbackFor = Exception.class)
public class FormManagerImpl implements FormManager {

    private static Logger log = LoggerFactory.getLogger(FormManagerImpl.class);

    @Autowired
    private IComponentService componentService;
    @Autowired
    private IFormModelService formModelService;
    @Autowired
    private TaskManager taskManager;
    @Autowired
    private RuleEngineManager ruleEngineManager;
    @Autowired
    private SecurityAdapter securityAdapter;
    @Autowired
    private DateTimeAdapter dateTimeAdapter;
    @Autowired
    private IdBuilder idBuilder;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private UserManager userManager;
    @Autowired
    private StringResolverFactory stringResolverFactory;
    @Autowired
    private FreemarkerBuilderAdapter freemarkerBuilderAdapter;
    @Autowired
    private IProcessService processService;


    @Override
    public ComponentDesignQuery createFormResourceQuery() {
        return componentService.createQuery();
    }

    @Override
    public FormModelQuery createFormModelQuery() {
        final FormModelQuery formModelQuery = formModelService.createQuery();
        return formModelQuery;
    }

    @Override
    public void submitTaskForm(String taskId, String formId, Map<String,Object> submitParams) {
        if(formId!=null) {
            final FormModel formModel = formModelService.createQuery().iid(formId).singleResult();
            vaild(formModel, submitParams);
            paramToDb(submitParams);
        }else{
            //formId 为空值说明这个任务没有配置表单
            log.warn("taskId={}没有配置表单！",taskId);
        }
        competeTask(taskId, submitParams);
    }

    @Override
    public void submitStartForm(FormModel formModel, Map<String, Object> submitParams) {
        if(formModel.getComponentDesign()==null){
            log.warn("id为{}的formModel的表单源没有配置",formModel.getIid());
        }

        if(formModel.getRuleEngine()==null || StringUtils.isEmpty(formModel.getRuleEngine().getExpression())){
            log.warn("id为{}的formModel没有配置规则引擎校验",formModel.getIid());
        }

        vaild(formModel,submitParams);
        paramToDb(submitParams);
    }

    @Override
    public void createFormResource(ComponentDesign formResource) {
        if(formResource.getIid()==null){
            formResource.setIid(idBuilder.getId());
        }
        formResource.setCreater(securityAdapter.getCurrentUser().getIid());
        formResource.setCreateTime(dateTimeAdapter.getCurrentDate());
        Assert.isTrue(componentService.insert(formResource),"用户表单源失败！");
    }

    @Override
    public void createFormModel(FormModel formModel) {
        if(formModel.getIid() == null){
            formModel.setIid(idBuilder.getId());
        }
        Assert.isTrue(formModelService.insert(formModel),"创建表单模型失败！");
    }

    @Override
    public void updateFormResource(ComponentDesign formResource) {
        Assert.isNotNull(formResource.getIid(),"表单源id不能为空！");
        formResource.setCreater(securityAdapter.getCurrentUser().getIid());
        formResource.setCreateTime(dateTimeAdapter.getCurrentDate());
        Assert.isTrue(componentService.updateById(formResource),"表单源更新失败！");
    }

    @Override
    public void updateFormModel(FormModel formModel) {
        Assert.isNotNull(formModel.getIid(),"表单模型id不能为空！");
        Assert.isTrue(formModelService.updateById(formModel),"表单模型更新失败！");
    }

    @Override
    public void deleteFormResource(String iid) {
        Assert.isNotNull(iid,"表单源id不能为空！");
        Assert.isTrue(componentService.deleteById(iid),"表单源删除失败！");
    }

    @Override
    public void deleteFormModel(String iid) {
        Assert.isNotNull(iid,"表单模型id不能为空！");
        Assert.isTrue(formModelService.deleteById(iid),"表单模型删除失败！");
    }

    @Override
    public FormModel getProcessCurrentFormModelById(String processInstanceId) {
        final Task currentTask = taskManager.getProcessCurrentTask(processInstanceId);
        if(currentTask!=null){
            final String formKey = currentTask.getFormKey();
            final FormModel formModel = formModelService.createQuery().iid(formKey).singleResult();
            //解析动态json
            freemarkerBuilderAdapter.resolverFormModelJson(formModel,currentTask);
            return formModel;
        }
        return null;
    }

    @Override
    public FormModel getProcessCurrentFormModelByKey(String processInstanceKey) {
        final ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processDefinitionKey(processInstanceKey).singleResult();
        final FormModel formModel = getProcessCurrentFormModelById(processInstance.getId());
        return formModel;
    }

    @Override
    public void createStartFormModel(String processId, FormModel formModel) {
        Assert.isNotNull(formModel,"formModel不能为空！");
        final Process process = processService.selectById(processId);
        createStartFormModel(process,formModel);
    }

    @Override
    public void createStartFormModel(Process process, FormModel formModel) {
        Assert.isNotNull(formModel,"formModel不能为空！");

        if(formModel.getIid() == null || formModelService.selectById(formModel.getIid())==null) {
            //如果id为空或者指定id没有查询到对应的formModel，就新建一条数据
            createFormModel(formModel);
        }

        process.setStartFormId(formModel.getIid());
        processService.updateById(process);

    }

    private void competeTask(String taskId, Map<String, Object> submitParams) {
        taskManager.completeTask(taskId, submitParams);
    }

    private void paramToDb(Map<String, Object> submitParams) {
        //TODO

    }


    private void vaild(FormModel formModel, Map<String,Object> submitParams) {
        final RuleEngine ruleEngine = formModel.getRuleEngine();
        if(ruleEngine!=null){
            //校验不通过会有异常抛出
            ruleEngineManager.executeRule(ruleEngine,submitParams);
        }
    }










}
